package com.neusoft.ch5.hw;

import java.util.Scanner;

public class HomeWorkCh5 {

	public static void main(String[] args) {
		//timesN();
		doArrAdd();
	}

	/**
	 * 矩阵乘法
	 * 规则（数学定理）：要求第一个矩阵的列数=第二个矩阵的行数，才可以进行矩阵乘法运算
	 * 
	 * 扩展：要求从控制台输入两个矩阵，并验证两个矩阵乘法的有效性，然后再进行矩阵乘法运算
	 *      或者，从控制台输入两个有效的矩阵，然后进行矩阵乘法运算
	 */
	private static void doArrAdd() {
		// 第一个矩阵
		int[][] arr0 = new int[][] { { 2, 3, 4 }, { 4, 6, 8 } };
		// 打印第一个数组
		System.out.println("第一个矩阵：");
		printArr2D(arr0);
		// 第二个矩阵
		int[][] arr1 = new int[][] { { 1, 5, 2, 8 }, { 5, 9, 10, -3 }, { 2, 7, -5, -18 } };
		// 打印第一个数组
		System.out.println("第二个矩阵：");
		printArr2D(arr1);
		// 计算矩阵乘法
		int[][] arrR = addArr(arr0, arr1);
		// 打印结果二维数组
		System.out.println("相乘结果矩阵：");
		printArr2D(arrR);
	}

	/**
	 * 矩阵乘法
	 * 
	 * @param arr0
	 *            第一个乘数矩阵
	 * @param arr1
	 *            第二个乘数矩阵
	 * @return 结果矩阵
	 */
	private static int[][] addArr(int[][] arr0, int[][] arr1) {
		// 返回的数组类型
		/*
		 * 返回结果数组：行数=第一个数组arr0的行数 
		 * 返回结果数组：列数=第二个数组arr1的列数
		 */
		int[][] arrR = new int[arr0.length][arr1[0].length];

		// 结果的行数：行数取决于第一个矩阵的行数
		// i是结果矩阵的行数，第一个矩阵的行数
		for (int i = 0; i < arr0.length; i++) {
			// 结果的列数：列数取决于第二个矩阵的列数
			// j是结果矩阵的列数，第二个矩阵的列数
			for (int j = 0; j < arr1[i].length; j++) {

				// 使用循环计算结果举证的元素值:
				// 结算结果
				int sum = 0;
				// k的值既可以是第一个矩阵的列数，也可以是第二个矩阵的行数
				for (int k = 0; k < arr1.length; k++) {
					sum += arr0[i][k] * arr1[k][j];
				}

				// 将计算结果赋值给结果矩阵
				arrR[i][j] = sum;
			}
		}
		// 返回值
		return arrR;
	}

	/**
	 * 打印二维数组
	 * 
	 * @param arr
	 *            打印的数组
	 */
	private static void printArr2D(int[][] arr) {
		// 遍历行数
		for (int i = 0; i < arr.length; i++) {
			// 遍历列
			for (int j = 0; j < arr[i].length; j++) {
				System.out.print("  " + arr[i][j]);
			}
			// 换行
			System.out.println();
		}
	}

	/**
	 * 计算阶乘（主方法）
	 */
	private static void timesN() {
		// 控制台输入一个整数
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个整数：");
		// 接收输入的整数
		int num = sc.nextInt();
		// 调用子函数计算阶乘并使用变量接收子函数返回的结果值
		double result = timesSub(num);
		// 使用子函数的结算结果进行其他业务逻辑处理
		System.out.println("1-" + num + "的累乘结果为：" + result);
	}

	/**
	 * 求整数num的阶乘（子方法）
	 * 
	 * @param num
	 *            所求的数
	 * @return 计算结果
	 */
	private static double timesSub(int num) {
		// 阶乘结果变量
		double result = 1L;
		// 循环计算累乘
		int num1 = 0;
		while (++num1 <= num) {
			result *= num1;
		}
		// 将计算结果返回给主函数
		return result;
	}

}
